/**
 * @author hary <hary@taomee.com>
 */
$.fn.dialog = function(options){

    return this.each(function(){
        Dialog(this, options);
    });
}

function Dialog(element, options){
    return this instanceof Dialog ? this.init(element, options) : new Dialog(element, options);
}

$.extend(Dialog, {
    VERSION: "1.0",
    AUTHOR: "HARY",
    DEFAULT_X: 50,
    DEFAULT_Y: 50,
	CENTER_TOP:100,
    zIndex: 1000,
    DEFAULTS: {
        closeOnEscape: true,
        closeBtn: '.dialog_close_btn',
        handle: '.dialog_handle',
        dragHandle: '.dialog_drag_handle',
        afterDrag: $.noop,
        show: 'fadeIn',//effect
        showTime: 300,
        afterShow: $.noop,
        hide: 'fadeOut',//effect
        hideTime: 300,
        afterHide: $.noop,
        modal: false,
        modalHideTime: 200,
		modalOpacity:0.5,
        beforeUnload: null,
        zIndex: 1000,
        center: true,
		cache:true,
        x: undefined,
        y: undefined
    },
    //LAYOUT: "<DIV CLASS='DIALOG_WRAP' STYLE=''></DIV>",
    IFRAMEMARKER: "<iframe src='about:blank' frameborder='0' border='0' style='border: 0px none ; position: absolute; top: 0px; left: 0px; z-index: -1; width: 100%; height: 100%;'></iframe>",
    dragable: false,
    resizable: false,
    dragging: false,
    _u: function(){
        for (var i = 0; i < arguments.length; i++) 
            if (typeof arguments[i] != 'undefined') 
                return false;
        return true;
    },
    _handleDrag: function(evt){
        var d = Dialog.dragging;
        
        if (Dialog.dragging) {
            d[0].Dialog.css({
                left: evt.pageX - d[1],
                top: evt.pageY - d[2]
            });
        }
        
    },
    _nextZ: function(){
        return Dialog.zIndex++;
    },
    //y x height width
    _viewport: function(){
        var d = document.documentElement, b = document.body, w = window;
        return $.extend($.browser.msie ? {
            left: b.scrollLeft || d.scrollLeft,
            top: b.scrollTop || d.scrollTop
        } : {
            left: w.pageXOffset,
            top: w.pageYOffset
        }, !Dialog._u(w.innerWidth) ? {
            width: w.innerWidth,
            height: w.innerHeight
        } : (!Dialog._u(d) && !Dialog._u(d.clientWidth) && d.clientWidth != 0 ? {
            width: d.clientWidth,
            height: d.clientHeight
        } : {
            width: b.clientWidth,
            height: b.clientHeight
        }));
    },
    load: function(url, options){
        options = options || {};
        
		if (options.cache) {
			if ($("[isload=true]").size()) {
				new Dialog($("[isload=true]"), options);
				return false;
			}
		}
        var ajax = {
            url: url,
            type: 'GET',
            dataType: 'html',
            cache: true,
			ifModify:true,
            success: function(html){
                html = jQuery(html);
                //if (options.filter) html = jQuery(options.filter, html);
                html.attr('isLoad', 'true');
                new Dialog(html, options);
            }
        };
        
        jQuery.each(['type', 'cache'], function(){
            if (this in options) {
                ajax[this] = options[this];
                delete options[this];
            }
        });
        
        jQuery.ajax(ajax);
    }
});

$.extend(Dialog.prototype, {
    init: function(element, options){
    
        var isLoading = false, dialogs = [], self = this;
        
        this.visible = false;
        this.options = $.extend(Dialog.DEFAULTS, options || {});
        this.Dialog  = $(element);
        
        this.Dialog.css({
            display: 'none'
        }).appendTo(document.body);
        this.toTop();
        
        if (this.options.modal) {
            this.options = $.extend(this.options, {
                center: true,
                draggable: false
            });
        }
        
        if ($.browser.msie && $.browser.version < 7) {
            this.Dialog.append(Dialog.IFRAMEMARKER);
        }
        
        if ($.browser.msie && $.browser.version < 7) {
            this.Dialog.css({
                position: 'absolute'
            });
        }
        else {
            this.Dialog.css({
                position: 'fixed'
            });
        }
        
        this.centerDo();
        this.show();
    },
    //如何在隐藏状态获取他的size
    estimateSize: function(){
        this.Dialog.css({
            visibility: 'hidden',
            display: 'block'
        });
        var dims = this.getSize();
        this.Dialog.css('display', 'none').css('visibility', 'visible');
        return dims;
    },
    getSize: function(){
        return [this.Dialog.width(), this.Dialog.height()];
    },
    getPosition: function(){
        var b = this.Dialog[0];
        return [b.offsetLeft, b.offsetTop];
    },
    getCenter: function(){
        var p = this.getPosition();
        var s = this.getSize();
        return [Math.floor(p[0] + s[0] / 2), Math.floor(p[1] + s[1] / 2)];
    },
    moveTo: function(x, y){
        this.moveToX(x).moveToY(y);
        return this;
    },
    moveToX: function(x){
        if (typeof x == 'number') 
            this.Dialog.css({
                left: x
            });
        else 
            this.centerX();
        return this;
    },
    moveToY: function(y){
        if (typeof y == 'number') 
            this.Dialog.css({
                top: y
            });
        else 
            this.centerY();
        return this;
    },
    /** original start**/
    centerAt: function(x, y){
        var s = this[this.visible ? 'getSize' : 'estimateSize']();
        if (typeof x == 'number') 
            this.moveToX(x - s[0] / 2);
        if (typeof y == 'number') 
            this.moveToY(y - s[1] / 2-Dialog.CENTER_TOP);
        return this;
    },
    centerAtX: function(x){
        return this.centerAt(x, null);
    },
    centerAtY: function(y){
        return this.centerAt(null, y);
    },
    /**original end**/
    /**specific start**/
    center: function(axis){
    
        var v = Dialog._viewport();
        var o = [v.left, v.top];
        if (!axis || axis == 'x') 
            this.centerAt(o[0] + v.width / 2, null);
        if (!axis || axis == 'y') 
            this.centerAt(null, o[1] + v.height / 2);
        
        return this;
    },
    centerX: function(){
        return this.center('x');
    },
    centerY: function(){
        return this.center('y');
    },
    isVisible: function(){
        return this.visible;
    },
    show: function(){
    
        if (this.isVisible()) 
            return;
        
        var self = this;
        
        if (self.options.modal) {
            var v = Dialog._viewport();
            self.modalBlackout = $('<div class="dialog-modal-blackout" style="background-color:gray;left:0;position:absolute;top:0;"></div>').css({
                zIndex: Dialog._nextZ(),
                width: ($.browser.msie&&$.browser.version < 7) ? v.width : $(document).width(),
                height: $(document).height()
            }).animate({
                opacity: Dialog.DEFAULTS.modalOpacity
            }, 0, function(){
                $(this).appendTo(document.body);
                self.toTop();
                self.Dialog.stop()[self.options.show](self.options.showTime, function(){
                    self.visible = true;
                    self._fire('afterShow');
                });
            });
        }
        else {
            self.Dialog.stop()[self.options.show](self.options.showTime, function(){
                self.visible = true;
                if (self.options.dragHandle != '' && !Dialog._u(self.options.dragHandle)) {
                    self._setupDrag();
                }
                self._fire('afterShow');
            });
        }
        
		if($.browser.msie&&$.browser.version < 7)
		{
			$(window).scroll(function(e){
				self.centerDo();
			});
		}
		
        if (self.options.closeBtn != '' && !Dialog._u(self.options.closeBtn)) {
            /*$(self.options.closeBtn).css({
                cursor: 'pointer'
            });*/
            $(self.options.closeBtn).mouseup(function(e){
                e.preventDefault();
                
                if (self.isVisible()) {
                    self.hide();
                }
                e.stopPropagation();
            });
        }
        if (self.options.closeOnEscape) {
            $(document).bind('keypress', function(evt){
                var key = evt.which || evt.keyCode;
                
                if (key == 27) {
                    self.hide();
                    $(document).unbind('keypress');
                }
            });
        }
		
		$(window).resize(function(){
			self.centerDo();
		});
		
        return this;
    },
    hide: function(){
    
        if (!this.visible) 
            return;
        
        var self = this;
        
        if (this.options.beforeUnload) {
            this._fire('beforeUnload');
            this.unload();
        }
        else {
            this.unload();
        }
        
        return this;
    },
    centerDo: function(){
    
        if (this.options.center && Dialog._u(this.options.x, this.options.y)) {
            this.center();
        }
        else {
            this.moveTo(!Dialog._u(this.options.x) ? this.options.x : Dialog.DEFAULT_X, !Dialog._u(this.options.y) ? this.options.y : Dialog.DEFAULT_Y);
        }
    },
    toggle: function(){
        this[this.visible ? 'hide' : 'show'](this.visible ? this.options.hideTime : this.options.showTime);
        return this;
    },
    unload: function(){
    
        var self = this;
        
        $(document).unbind('keypress');
        $(document).unbind('mousemove');
        $(this.options.dragHandle).unbind('mousedown');
        $(this.options.dragHandle).unbind('mouseup');
        $(window).unbind('scroll');
		$(window).unbind('resize');
		
        if (this.options.modal) {
        
            this.modalBlackout.fadeOut(self.options.modalHideTime, function(){
                $(this).remove();
                self._fire('afterHide');
            });
            this.Dialog.stop()[this.options.hide](this.options.hideTime, function(){
                self.Dialog.css({
                    display: 'none'
                });
                self.visible = false;
            });
        }
        else {
            this.Dialog.stop()[this.options.hide](self.options.hideTime, function(){
                self.Dialog.css({
                    display: 'none'
                });
                self.visible = false;
                self._fire('afterHide');
                
            });
            
        }
    },
    toTop: function(){
        this.Dialog.css({
            zIndex: Dialog._nextZ()
        });
        return this;
    },
    _setupDrag: function(){
    
        var self = this;
        
        var drh = $(this.options.dragHandle);
        
        drh.mousedown(function(evt){
            evt.stopPropagation();
            self.toTop();
            $.data(Dialog, 'lastMouseX', evt.pageX);
            $.data(Dialog, 'lastMouseY', evt.pageY);
            Dialog.dragging = [self, evt.pageX - self.Dialog[0].offsetLeft, evt.pageY - self.Dialog[0].offsetTop];//offsetLeft = offset().left
            $(document).unbind('mousemove').mousemove(function(e){
                Dialog._handleDrag(e);
            });
        }).mouseup(function(evt){
            evt.stopPropagation();
            Dialog.dragging = null;
            var lastX = $.data(Dialog, 'lastMouseX');
            var lastY = $.data(Dialog, 'lastMouseY');
            
            if (lastX == evt.pageX && lastY == evt.pageY) 
                return false;
            
            $(document).unbind('mousemove');
            self._fire('afterDrag');
        });
        
        drh.css({
            cursor: 'move'
        });
    },
    _fire: function(event){
        this.options[event].call(this);
    },
    _queue: function(name, arrayFunc){
        $(document).queue(name, arrayFunc);
    },
    _triggerQueue: function(name){
        $(document).dequeue(name);
    }
});

$.fn.android = function(time, func){

    time = !typeof time == 'number' ? time : 400;
    func = $.isFunction(func) ? func : $.noop;
    
    $(this).stop().css({
        display: '',
        opacity: 0
    }).animate({
        opacity: 0.5
    }, 300, function(){
        $(this).animate({
            opacity: 1
        }, 100, function(){
            func();
        });
    });
}

$.fn.dropOut = function(time, func){

    var w = $(this).width();
	var left = $(this).offset().left;
    
    time = typeof time == 'number' ? time : 400;
    func = $.isFunction(func) ? func : $.noop;
    
    $(this).stop().css({
        display: '',
        opacity: 0.4
    }).animate({
        opacity: 0,
        left: left-50 + 'px'
    }, time, function(){
        func();
    });
}
$.fn.dropIn = function(time, func){

    var w = $(this).width();
    time = typeof time == 'number' ? time : 400;
    func = $.isFunction(func) ? func : $.noop;
    
    $(this).stop().css({
		overflow:'hidden',
        opacity: 0.3,
        width: '0px'
    }).animate({
        opacity: 1,
        width: w + 'px'
    }, time, function(){
        func();
    });
}

